<script>
import { add, batchDelete, page, update } from '@/api/questionBank';
import { tree } from '@/api/questionBankCategory';
import { FilterMatchMode } from '@primevue/core/api';
import Button from 'primevue/button';
import InputText from 'primevue/inputtext';
import SelectButton from 'primevue/selectbutton';
import { useToast } from 'primevue/usetoast';
import Dropdown from 'primevue/dropdown';
import Calendar from 'primevue/calendar';
import FileUpload from 'primevue/fileupload';
import Textarea from 'primevue/textarea';
import TreeSelect from 'primevue/treeselect';
import { formatDateTime } from '@/utils/datetimeutil';
import { uploadImage } from '@/api/common';

export default {
    components: {
        InputText,
        Button,
        SelectButton,
        Dropdown,
        Calendar,
        FileUpload,
        Textarea,
        TreeSelect
    },
    data() {
        return {
            questionBanks: [],
            questionBank: {
                id: null,
                name: '',
                description: '',
                category: null,
                cover: '',
                type: null,
                language: null,
                sort: 0,
                status: 1,
                createTime: null,
                updateTime: null
            },
            types: [
                { label: '普通', value: 0 },
                { label: '热门', value: 1 },
                { label: '推荐', value: 2 }
            ],
            languages: [
                { label: '中文', value: 1 },
                { label: '英文', value: 0 }
            ],
            selectedQuestionBanks: null,
            newQuestionBankDialog: false,
            editQuestionBankDialog: false,
            deleteQuestionBankDialog: false,
            deleteQuestionBanksDialog: false,
            submitted: false,
            loading: false,
            filters: {
                global: { value: null, matchMode: FilterMatchMode.CONTAINS }
            },
            pageSize: 10,
            pageNum: 1,
            totalRecords: 0,
            searchQuery: {
                id:null,
                name: null,
                category: null,
                type: null,
                language: null,
                createTimeRange: null,
                updateTimeRange: null,
                status: null
            },
            statuses: [
                { label: '有效', value: 1 },
                { label: '无效', value: 0 }
            ],
            categories: [],
            selectedCategory: null
        };
    },
    mounted() {
        this.loadQuestionBanks();
        this.loadCategories();
    },
    methods: {
        async loadQuestionBanks() {
            // 处理分类ID，如果是对象格式，提取ID
            if (this.searchQuery.category && typeof this.searchQuery.category === 'object') {
                const keys = Object.keys(this.searchQuery.category);
                if (keys.length > 0) {
                    this.searchQuery.category = parseInt(keys[0]);
                }
            }
            this.loading = true;
            try {
                const params = {
                    pageNum: this.pageNum,
                    pageSize: this.pageSize,
                    ...this.searchQuery
                };

                if (this.searchQuery.createTimeRange) {
                    params.createTimeStart = formatDateTime(this.searchQuery.createTimeRange[0]);
                    params.createTimeEnd = formatDateTime(this.searchQuery.createTimeRange[1]);
                }
                delete params.createTimeRange;

                if (this.searchQuery.updateTimeRange) {
                    params.updateTimeStart = formatDateTime(this.searchQuery.updateTimeRange[0]);
                    params.updateTimeEnd = formatDateTime(this.searchQuery.updateTimeRange[1]);
                }
                delete params.updateTimeRange;

                const response = await page(params);

                if (response.code === 200) {
                    this.questionBanks = response.data.list || [];
                    this.totalRecords = response.data.total || 0;
                } else {
                    this.$toast.add({
                        severity: 'error',
                        summary: '加载失败',
                        detail: response.message || '无法加载题库数据',
                        life: 3000
                    });
                }
            } catch (error) {
                this.$toast.add({
                    severity: 'error',
                    summary: '加载失败',
                    detail: '无法加载题库数据',
                    life: 3000
                });
            } finally {
                this.loading = false;
            }
        },
        resetSearch() {
            this.searchQuery = {
                id:null,
                name: null,
                category: null,
                type: null,
                language: null,
                createTimeRange: null,
                updateTimeRange: null,
                status: null
            };
            this.loadQuestionBanks();
        },
        onPage(event) {
            console.log(event)
            this.pageNum = event.page + 1;
            this.pageSize = event.rows;
            this.loadQuestionBanks();
        },
        onSort(event) {
            let sortField = event.sortField;
            let sortOrder = event.sortOrder;
            if (sortField) {
                this.questionBanks.sort((a, b) => {
                    let result = 0;
                    if (a[sortField] < b[sortField]) {
                        result = -1;
                    } else if (a[sortField] > b[sortField]) {
                        result = 1;
                    }
                    return sortOrder === 1 ? result : -result;
                });
            }
        },
        async performSearch() {
            this.pageNum = 1;
            await this.loadQuestionBanks();
            this.searchQuery.category = {
                [this.searchQuery.category]: true
            };
        },
        openNew() {
            this.questionBank = {
                id: null,
                name: '',
                description: '',
                category: null,
                cover: '',
                type: null,
                language: null,
                sort: 0,
                status: 1,
                createTime: null,
                updateTime: null
            };
            this.selectedCategory = null;
            this.submitted = false;
            this.newQuestionBankDialog = true;
        },
        hideNewDialog() {
            this.newQuestionBankDialog = false;
            this.submitted = false;
            this.resetQuestionBank();
        },
        editQuestionBank(questionBank) {
            this.questionBank = { ...questionBank };

            // 设置选中的分类ID
            this.selectedCategory = {
                [questionBank.category]: true
            };

            this.editQuestionBankDialog = true;
        },
        hideEditDialog() {
            this.editQuestionBankDialog = false;
            this.submitted = false;
            this.resetQuestionBank();
        },
        resetQuestionBank() {
            this.questionBank = {
                id: null,
                name: '',
                description: '',
                category: null,
                cover: '',
                type: null,
                language: null,
                sort: 0,
                status: 1,
                createTime: null,
                updateTime: null
            };
        },
        async saveQuestionBank() {
            this.submitted = true;

            if (!this.questionBank.name?.trim()) {
                return;
            }

            try {
                this.loading = true;

                // 创建一个新对象用于API请求
                const requestData = { ...this.questionBank };

                // 确保 category 是正确的格式
                if (requestData.category && typeof requestData.category === 'object') {
                    const keys = Object.keys(requestData.category);
                    if (keys.length > 0) {
                        requestData.category = parseInt(keys[0]);
                    }
                }

                const isEdit = !!requestData.id;
                const response = isEdit ? await update(requestData) : await add(requestData);

                if (response.code === 200) {
                    this.$toast.add({
                        severity: 'success',
                        summary: '成功',
                        detail: isEdit ? '题库已更新' : '题库已创建',
                        life: 3000
                    });

                    if (isEdit) {
                        this.editQuestionBankDialog = false;
                    } else {
                        this.newQuestionBankDialog = false;
                    }

                    this.resetQuestionBank();

                    await this.loadQuestionBanks();
                } else {
                    this.$toast.add({
                        severity: 'error',
                        summary: '失败',
                        detail: response.message || '保存题库失败',
                        life: 3000
                    });
                }
            } catch (error) {
                this.$toast.add({
                    severity: 'error',
                    summary: '错误',
                    detail: '保存题库时出错',
                    life: 3000
                });
            } finally {
                this.loading = false;
            }
        },
        confirmDeleteQuestionBank(questionBank) {
            this.questionBank = questionBank;
            this.deleteQuestionBankDialog = true;
        },
        async deleteQuestionBank() {
            try {
                this.loading = true;
                const response = await batchDelete([this.questionBank.id]);

                if (response.code === 200) {
                    this.$toast.add({
                        severity: 'success',
                        summary: '成功',
                        detail: '题库已删除',
                        life: 3000
                    });
                    this.deleteQuestionBankDialog = false;

                    this.resetQuestionBank();

                    this.loadQuestionBanks();
                } else {
                    this.$toast.add({
                        severity: 'error',
                        summary: '失败',
                        detail: response.message || '删除题库失败',
                        life: 3000
                    });
                }
            } catch (error) {
                this.$toast.add({
                    severity: 'error',
                    summary: '错误',
                    detail: '删除题库时出错',
                    life: 3000
                });
            } finally {
                this.loading = false;
                this.deleteQuestionBankDialog = false;
            }
        },
        confirmDeleteSelected() {
            this.deleteQuestionBanksDialog = true;
        },
        async deleteSelectedQuestionBanks() {
            try {
                this.loading = true;
                const ids = this.selectedQuestionBanks.map((qb) => qb.id);
                const response = await batchDelete(ids);

                if (response.code === 200) {
                    this.$toast.add({
                        severity: 'success',
                        summary: '成功',
                        detail: '选中的题库已删除',
                        life: 3000
                    });
                    this.selectedQuestionBanks = null;
                    this.deleteQuestionBanksDialog = false;
                    this.loadQuestionBanks();
                } else {
                    this.$toast.add({
                        severity: 'error',
                        summary: '失败',
                        detail: response.message || '批量删除题库失败',
                        life: 3000
                    });
                }
            } catch (error) {
                this.$toast.add({
                    severity: 'error',
                    summary: '错误',
                    detail: '批量删除题库时出错',
                    life: 3000
                });
            } finally {
                this.loading = false;
                this.deleteQuestionBanksDialog = false;
            }
        },
        exportCSV() {
            this.$refs.dt.exportCSV();
        },
        async handleImageUpload(event) {
            const file = event.files[0];
            if (file) {
                try {
                    // 创建 FormData 对象
                    const formData = new FormData();
                    formData.append('file', file);
                    formData.append('type', 0); // 使用题库类型 0

                    // 显示上传中提示
                    this.$toast.add({
                        severity: 'info',
                        summary: '上传中',
                        detail: '正在上传图片...',
                        life: 3000
                    });

                    // 调用上传接口
                    const response = await uploadImage(formData);

                    if (response.code === 200) {
                        // 上传成功，设置封面 URL
                        this.questionBank.cover = response.data;

                        this.$toast.add({
                            severity: 'success',
                            summary: '上传成功',
                            detail: '图片上传成功',
                            life: 3000
                        });
                    } else {
                        this.$toast.add({
                            severity: 'error',
                            summary: '上传失败',
                            detail: response.message || '图片上传失败',
                            life: 3000
                        });
                    }
                } catch (error) {
                    this.$toast.add({
                        severity: 'error',
                        summary: '上传错误',
                        detail: '图片上传过程中发生错误',
                        life: 3000
                    });
                }
            }
        },
        transformCategories(categories) {
            if (!categories || categories.length === 0) return [];

            return categories.map((category) => {
                return {
                    key: category.id.toString(),
                    label: category.name,
                    data: category.id,
                    children: category.children ? this.transformCategories(category.children) : []
                };
            });
        },
        async loadCategories() {
            try {
                const response = await tree();
                if (response.code === 200) {
                    this.categories = this.transformCategories(response.data || []);
                } else {
                    this.$toast.add({
                        severity: 'error',
                        summary: '加载失败',
                        detail: response.message || '无法加载分类数据',
                        life: 3000
                    });
                }
            } catch (error) {
                this.$toast.add({
                    severity: 'error',
                    summary: '加载失败',
                    detail: '无法加载分类数据',
                    life: 3000
                });
            }
        },
        handleCategoryChange(value) {
            // 如果值是对象形式 ({id: true})，提取ID
            if (value && typeof value === 'object') {
                const keys = Object.keys(value);
                if (keys.length > 0) {
                    this.questionBank.category = parseInt(keys[0]);
                } else {
                    this.questionBank.category = null;
                }
            } else {
                // 如果是直接的值，保持不变
                this.questionBank.category = value;
            }
        }
    },
    setup() {
        const toast = useToast();
        return { toast };
    }
};
</script>

<template>
    <div>
        <div class="card">
            <Toast />
            <Toolbar class="mb-6">
                <template #start>
                    <Button label="新增题库" icon="pi pi-plus" severity="secondary" class="mr-2" @click="openNew" />
                    <Button label="批量删除" icon="pi pi-trash" severity="secondary" @click="confirmDeleteSelected" :disabled="!selectedQuestionBanks || !selectedQuestionBanks.length" />
                </template>
                <template #end>
                    <Button label="导出" icon="pi pi-upload" severity="secondary" @click="exportCSV($event)" />
                </template>
            </Toolbar>
            <Toolbar class="mb-6">
                <template #start>
                    <div class="flex flex-wrap items-center gap-2">
                        <InputText v-model="searchQuery.id" placeholder="题库ID" class="mr-2" />
                        <InputText v-model="searchQuery.name" placeholder="题库名称" class="mr-2" />

                        <TreeSelect v-model="searchQuery.category" :options="categories" selectionMode="single" placeholder="题库分类" class="mr-2 w-12rem" :filter="true" :showClear="true" />

                        <Dropdown v-model="searchQuery.type" :options="types" optionLabel="label" optionValue="value" placeholder="题库类型" class="mr-2" :showClear="true" />
<!--                        <Dropdown v-model="searchQuery.language" :options="languages" optionLabel="label" optionValue="value" placeholder="题库语言" class="mr-2" :showClear="true" />-->
                        <Dropdown v-model="searchQuery.status" :options="statuses" optionLabel="label" optionValue="value" placeholder="题库状态" class="mr-2" :showClear="true" />

                        <!-- 修改日期选择器部分 -->
                        <DatePicker
                            showButtonBar
                            v-model="searchQuery.createTimeRange"
                            style="width: 300px"
                            selectionMode="range"
                            :showIcon="true"
                            placeholder="题库创建时间"
                            class="mr-2"
                            dateFormat="yy-mm-dd"
                            hourFormat="24"
                            showTime
                            timeFormat="HH:mm:ss"
                            :manualInput="false"
                        />

                        <DatePicker
                            showButtonBar
                            v-model="searchQuery.updateTimeRange"
                            style="width: 300px"
                            selectionMode="range"
                            :showIcon="true"
                            placeholder="题库修改时间"
                            class="mr-2"
                            dateFormat="yy-mm-dd"
                            hourFormat="24"
                            showTime
                            timeFormat="HH:mm:ss"
                            :manualInput="false"
                        />
                        <Button v-if="Object.values(searchQuery).some((value) => value !== null && value !== '')" label="重置" icon="pi pi-eraser" severity="info" @click="resetSearch" color="mr-2" />
                    </div>
                </template>
                <template #end>
                    <Button label="Search" icon="pi pi-search" @click="performSearch" />
                </template>
            </Toolbar>
            <DataTable
                v-model:selection="selectedQuestionBanks"
                :value="questionBanks"
                dataKey="id"
                :paginator="true"
                :rows="pageSize"
                :totalRecords="totalRecords"
                scrollable
                lazy
                :loading="loading"
                @sort="onSort($event)"
                @page="onPage($event)"
                :filters="filters"
                paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
                :rowsPerPageOptions="[5, 10, 20, 50]"
                currentPageReportTemplate="显示 {first} 到 {last} 共 {totalRecords} 条记录"
            >
                <template #header>
                    <h4 class="m-0">题库管理</h4>
                </template>

                <Column selectionMode="multiple" style="width: 3rem" :exportable="false"></Column>
                <Column field="id" frozen header="ID" sortable style="min-width: 5rem" bodyClass="text-center"></Column>
                <Column field="name" frozen header="题库名称" sortable style="min-width: 16rem" bodyClass="text-center"></Column>
                <Column field="description" header="描述" sortable style="min-width: 16rem" bodyClass="text-center"></Column>
                <Column field="categoryName" header="分类名称" sortable style="min-width: 10rem" bodyClass="text-center"></Column>
<!--                <Column header="Image" bodyClass="text-center">-->
<!--                    <template #body="slotProps">-->
<!--                        <img :src="slotProps.data.cover" :alt="slotProps.data.cover" class="rounded" style="width: 64px" />-->
<!--                    </template>-->
<!--                </Column>-->
                <Column field="type" header="类型" sortable style="min-width: 10rem" bodyClass="text-center">
                    <template #body="slotProps">
                        <Tag severity="info" :value="types.find((t) => t.value === slotProps.data.type)?.label || '未知'" />
                    </template>
                </Column>
                <Column field="language" header="语言" sortable style="min-width: 10rem" bodyClass="text-center">
                    <template #body="slotProps">
                        <Tag :value="languages.find((l) => l.value === slotProps.data.language)?.label || '未知'" />
                    </template>
                </Column>
                <Column field="status" header="状态" sortable style="min-width: 10rem" bodyClass="text-center">
                    <template #body="slotProps">
                        <Tag :severity="slotProps.data.status === 1 ? 'success' : 'danger'" :value="statuses.find((s) => s.value === slotProps.data.status)?.label || '未知'" />
                    </template>
                </Column>
                <Column bodyClass="text-center" field="viewNum" header="浏览数" sortable style="min-width: 10rem"></Column>
                <Column bodyClass="text-center" field="collectionNum" header="收藏数" sortable style="min-width: 10rem"></Column>
                <Column field="sort" header="排序" sortable style="min-width: 10rem" bodyClass="text-center"></Column>
                <Column field="createTime" header="创建时间" sortable style="min-width: 15rem" bodyClass="text-center"></Column>
                <Column field="updateTime" header="更新时间" sortable style="min-width: 15rem" bodyClass="text-center"></Column>
                <Column frozen alignFrozen="right" header="操作" style="min-width: 10rem" bodyClass="text-center">
                    <template #body="slotProps">
                        <Button icon="pi pi-pencil" outlined rounded class="mr-2" @click="editQuestionBank(slotProps.data)" />
                        <Button icon="pi pi-trash" outlined rounded severity="danger" @click="confirmDeleteQuestionBank(slotProps.data)" />
                    </template>
                </Column>
            </DataTable>
        </div>

        <Dialog v-model:visible="newQuestionBankDialog" :style="{ width: '450px' }" header="新增题库" :modal="true" class="p-fluid">
            <div class="flex flex-col gap-6">
                <div>
                    <label for="name" class="block font-bold mb-3">名称</label>
                    <InputText id="name" v-model.trim="questionBank.name" required="true" autofocus :invalid="!questionBank.name" fluid />
                    <small v-if="submitted && !questionBank.name" class="text-red-500">名称是必须的</small>
                </div>
                <div>
                    <label for="description" class="block font-bold mb-3">描述</label>
                    <Textarea id="description" v-model="questionBank.description" rows="3" cols="20" fluid />
                </div>
                <div>
                    <label for="categoryId" class="block font-bold mb-3">分类</label>
                    <TreeSelect id="categoryId" v-model="selectedCategory" :options="categories" selectionMode="single" placeholder="选择分类" class="w-full" :filter="true" :showClear="true" @update:modelValue="handleCategoryChange" />
                    <small v-if="submitted && !questionBank.category" class="text-red-500">分类是必须的</small>
                </div>
                <div>
                    <label for="cover" class="block font-bold mb-3">封面</label>
                    <div class="flex flex-col gap-2">
                        <img v-if="questionBank.cover" :src="questionBank.cover" class="w-20 h-20 object-cover rounded" />
                        <FileUpload mode="basic" :auto="true" accept="image/*" :maxFileSize="1000000" @select="handleImageUpload" chooseLabel="选择图片" class="w-full" :showUploadButton="false" :showCancelButton="false" :showRemoveButton="false">
                            <template #empty>
                                <div class="flex items-center justify-center p-4">
                                    <span>拖拽图片到这里或点击上传</span>
                                </div>
                            </template>
                        </FileUpload>
                    </div>
                </div>
                <div>
                    <label for="type" class="block font-bold mb-3">类型</label>
                    <SelectButton id="type" v-model="questionBank.type" :options="types" optionLabel="label" optionValue="value" />
                </div>
                <div>
                    <label for="language" class="block font-bold mb-3">语言</label>
                    <SelectButton id="language" v-model="questionBank.language" :options="languages" optionLabel="label" optionValue="value" />
                </div>
                <div>
                    <label for="sort" class="block font-bold mb-3">排序</label>
                    <InputNumber v-keyfilter.int id="sort" v-model="questionBank.sort" :min="0" rows="3" cols="20" fluid />
                </div>
                <div>
                    <label for="status" class="block font-bold mb-3">状态</label>
                    <SelectButton id="status" v-model="questionBank.status" :options="statuses" optionLabel="label" optionValue="value" />
                </div>
            </div>
            <template #footer>
                <Button label="取消" icon="pi pi-times" text @click="hideNewDialog" />
                <Button label="保存" icon="pi pi-check" @click="saveQuestionBank" />
            </template>
        </Dialog>

        <Dialog v-model:visible="editQuestionBankDialog" :style="{ width: '450px' }" header="编辑题库" :modal="true" class="p-fluid">
            <div class="flex flex-col gap-6">
                <div>
                    <label for="edit-cover" class="block font-bold mb-3">封面</label>
                    <div class="flex flex-col gap-2">
                        <div class="flex flex-col gap-2 items-center"><Image preview v-if="questionBank.cover" :src="questionBank.cover" class="object-cover rounded" /></div>

                        <FileUpload mode="basic" :auto="true" accept="image/*" :maxFileSize="1000000" @select="handleImageUpload" chooseLabel="选择图片" class="w-full" :showUploadButton="false" :showCancelButton="false" :showRemoveButton="false">
                            <template #empty>
                                <div class="flex items-center justify-center p-4">
                                    <span>拖拽图片到这里或点击上传</span>
                                </div>
                            </template>
                        </FileUpload>
                    </div>
                </div>
                <div>
                    <label for="edit-id" class="block font-bold mb-3">ID</label>
                    <InputText id="edit-id" disabled v-model.trim="questionBank.id" fluid />
                </div>
                <div>
                    <label for="edit-name" class="block font-bold mb-3">名称</label>
                    <InputText id="edit-name" v-model.trim="questionBank.name" required="true" autofocus :invalid="!questionBank.name" fluid />
                    <small v-if="submitted && !questionBank.name" class="text-red-500">名称是必须的</small>
                </div>
                <div>
                    <label for="edit-description" class="block font-bold mb-3">描述</label>
                    <Textarea id="edit-description" v-model="questionBank.description" rows="3" cols="20" fluid />
                </div>
                <div>
                    <label for="edit-categoryId" class="block font-bold mb-3">分类</label>
                    <TreeSelect id="edit-categoryId" v-model="selectedCategory" :options="categories" selectionMode="single" placeholder="选择分类" class="w-full" :filter="true" :showClear="true" @update:modelValue="handleCategoryChange" />
                    <small v-if="submitted && !questionBank.category" class="text-red-500">分类是必须的</small>
                </div>

                <div>
                    <label for="edit-type" class="block font-bold mb-3">类型</label>
                    <SelectButton id="edit-type" v-model="questionBank.type" :options="types" optionLabel="label" optionValue="value" />
                </div>
                <div>
                    <label for="edit-language" class="block font-bold mb-3">语言</label>
                    <SelectButton id="edit-language" v-model="questionBank.language" :options="languages" optionLabel="label" optionValue="value" />
                </div>
                <div>
                    <label for="edit-sort" class="block font-bold mb-3">排序</label>
                    <InputNumber v-keyfilter.int id="edit-sort" v-model="questionBank.sort" :min="0" rows="3" cols="20" fluid />
                </div>
                <div>
                    <label for="edit-status" class="block font-bold mb-3">状态</label>
                    <SelectButton id="edit-status" v-model="questionBank.status" :options="statuses" optionLabel="label" optionValue="value" />
                </div>
            </div>
            <template #footer>
                <Button label="取消" icon="pi pi-times" text @click="hideEditDialog" />
                <Button label="保存" icon="pi pi-check" @click="saveQuestionBank" />
            </template>
        </Dialog>

        <Dialog v-model:visible="deleteQuestionBankDialog" :style="{ width: '450px' }" header="确认删除" :modal="true">
            <div class="flex items-center gap-4">
                <i class="pi pi-exclamation-triangle !text-3xl" />
                <span v-if="questionBank"
                    >确定要删除题库 <b>{{ questionBank.name }}</b> 吗？</span
                >
            </div>
            <template #footer>
                <Button label="取消" icon="pi pi-times" text @click="deleteQuestionBankDialog = false" />
                <Button label="确定" icon="pi pi-check" severity="danger" @click="deleteQuestionBank" />
            </template>
        </Dialog>

        <Dialog v-model:visible="deleteQuestionBanksDialog" :style="{ width: '450px' }" header="确认删除" :modal="true">
            <div class="flex items-center gap-4">
                <i class="pi pi-exclamation-triangle !text-3xl" />
                <span>确定要删除选中的题库吗？</span>
            </div>
            <template #footer>
                <Button label="取消" icon="pi pi-times" text @click="deleteQuestionBanksDialog = false" />
                <Button label="确定" icon="pi pi-check" severity="danger" @click="deleteSelectedQuestionBanks" />
            </template>
        </Dialog>
    </div>
</template>
